﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.ComponentModel;
using System.Threading;
using System.Globalization;
using System.Timers;


namespace ASCM_MulticopterApp
{
    class PhoneClient : IDisposable
    {

        public event CurrentFps on_fps_refresh;
        public delegate void CurrentFps(string fps);

        public delegate void OnStatusChanged(string msg, bool status);
        public event OnStatusChanged on_status_change;

        BackgroundWorker backgroundWorker;
        private static System.Timers.Timer _timer;

        Socket sender; 
        byte[] bytes_buff = new byte[22];//ker je dolžina sporočila fiksna
        public int X, Y, Z, Throttle;



        public bool connect(string ipAddress, int port)
        {


            try
            {

                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ipAddress), port);

                sender = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);
               // sender.Connect(remoteEP);

                IAsyncResult result = sender.BeginConnect(remoteEP,null,null);
                //timeout 2 sekunde
                bool success = result.AsyncWaitHandle.WaitOne(2000, true);

                if (!success)
                {

                    sender.Close();
                    return false;
                }

                backgroundWorker = new BackgroundWorker();
                backgroundWorker.DoWork += backgroundWorker1_DoWork1;
                // backgroundWorker.DoWork += backgroundWorker1_DoWork;
                backgroundWorker.WorkerReportsProgress = true;
                backgroundWorker.WorkerSupportsCancellation = true;
                backgroundWorker.RunWorkerAsync();


            }
            catch
            {
                System.Diagnostics.Debug.WriteLine("Connection error");
                return false;
            }

            return true;
        }

        public bool Disconnect()
        {
            if (sender.Connected)
            {
                sender.Dispose();

                backgroundWorker.CancelAsync();
            }
            return true;
        }
        bool SendRequest()
        {


            byte[] _msg = Encoding.ASCII.GetBytes("pingam");

            try
            {
                //pošlji "ping"
                sender.Send(_msg);

                //prejmi
                sender.Receive(bytes_buff);
            }
            catch
            {
                throw new Exception();
            }


            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();

            string sRecieved = enc.GetString(bytes_buff);


            if (sRecieved.Length < 22)
            {
                Console.WriteLine("lenght error" + sRecieved);
                return false;
            }

            //preveri P111 222 333 444 1000#

            if (sRecieved[0] == 'P' && sRecieved[sRecieved.Length - 1] == '#')
            {
                try
                {

                    sRecieved = sRecieved.Remove(0, 1);
                    sRecieved = sRecieved.Remove(sRecieved.Length - 1, 1);
                    string[] temp = sRecieved.Split(':');

                    //napaka če se seštevek vrednosti kanalov ne ujema s kontrolno vsoto
                    if (Convert.ToInt32(temp[4]) == Convert.ToInt32(temp[0]) +
                        Convert.ToInt32(temp[1]) + Convert.ToInt32(temp[2]) + Convert.ToInt32(temp[3]))
                        return false;

                    //shrani v public spremenljivke
                    Throttle = Convert.ToInt32(temp[0]);
                    X = Convert.ToInt32(temp[1]);
                    Y = Convert.ToInt32(temp[0]);
                    Z = Convert.ToInt32(temp[3]);


                     on_status_change("Connected to phone", true);
                }
                catch (Exception e)
                {
                    Console.WriteLine("error" + sRecieved);
                }
                return true;
            }

            return false;
        }

        public void CountFps()
        {
            _timer = new System.Timers.Timer(1000);
            _timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            _timer.Enabled = true;
        }

        //TODO: noče povečevati števca v backgroundworkerju
        private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            // SendRequest();

            on_fps_refresh(count.ToString());
            count = 0;
        }

        int count = 0;

       
       

        private void backgroundWorker1_DoWork1(object sender, DoWorkEventArgs e)
        {
            while (true)
            {

                Task.Delay(10);

                try
                {
                    SendRequest();
                    count++;

                }
                catch
                {
                    backgroundWorker.CancelAsync();
                }

            }
        }

        // TODO: ne zaključi timerja, uredi
        public void Dispose()
        {

            backgroundWorker.CancelAsync();
            //sender.Dispose();
            // /sender.Shutdown(SocketShutdown.Both);
            //sender.Close();
        }

    }
}